#pragma once
#include <string>
#include <sstream>

using namespace std;

template<class K, class V>
struct Node
{
	Node<K, V>(K key, V value)
		{ this->key = key, this->value = value, this->next = nullptr; }
	K key;
	V value;
	Node<K, V> *next;
};

template<class K, class V>
class EnkelLista
{
private:
	Node<K, V> *head;
	Node<K, V> *tail;
public:
	//Default construktor
	EnkelLista()
	{
		head = tail = nullptr;
	}

	//Copy constructor
	EnkelLista(const EnkelLista &list)
	{
		Node<K, V> *n = list.head;
		while (n != nullptr)
		{
			this->add_at_head(n->key);
			this->add_at_head(n->value);
			n = n->next;
		}
	}

	~EnkelLista()
	{
		Node<K, V> *n = head;
		Node<K, V> *d;
		while (n != nullptr)
		{
			d = n;
			n = n->next;
 			delete d;
		}
	}

	void add_at_head(Node<K,V> &n)
	{
		if (head == nullptr)
		{
			head = n;
			tail = head;
		}
		else
		{
			n->next = head;
			head = n;
		}
	}

	void add_at_tail(Node<K,V> &n)
	{
		if (head == nullptr)
		{
			head = &n;
			tail = head;
		}
		else
		{
			tail->next = &n;
			tail = tail->next;
		}
	}

	void add(Node<K, V> &n, Node<K, V> *afterNode)
	{
		n.next = afterNode->next;
		afterNode->next = &n;
	}

	string str()
	{
		ostringstream oss;

		Node<K, V> *n = head;
		if (n == nullptr)
			return "";
		else
		{
			do
			{
				oss << n->key << " " << n->value;
				n = n->next;
			} while (n != nullptr);
		}

		return oss.str();
	}
};

